package cloud.seri.pay.config

import cloud.seri.pay.config.oauth2.OAuth2JwtAccessTokenConverter
import cloud.seri.pay.config.oauth2.OAuth2Properties
import cloud.seri.pay.security.AuthoritiesConstants
import cloud.seri.pay.security.oauth2.OAuth2SignatureVerifierClient
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter
import org.springframework.security.oauth2.provider.token.TokenStore
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore
import org.springframework.web.client.RestTemplate

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration(private val oAuth2Properties: OAuth2Properties) : ResourceServerConfigurerAdapter()
{

    @Throws(Exception::class)
    override fun configure(http: HttpSecurity)
    {
        http.csrf()
            .disable()
            .headers()
            .frameOptions()
            .disable()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/api/**").authenticated()
            .antMatchers("/management/**").permitAll()
//            .antMatchers("/management/info").permitAll()
//            .antMatchers("/management/prometheus").permitAll()
//            .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
    }

    @Bean
    fun tokenStore(jwtAccessTokenConverter: JwtAccessTokenConverter): TokenStore
    {
        return JwtTokenStore(jwtAccessTokenConverter)
    }

    @Bean
    fun jwtAccessTokenConverter(signatureVerifierClient: OAuth2SignatureVerifierClient): JwtAccessTokenConverter
    {
        return OAuth2JwtAccessTokenConverter(oAuth2Properties, signatureVerifierClient)
    }

    @Bean
    @Qualifier("loadBalancedRestTemplate")
    fun loadBalancedRestTemplate(customizer: RestTemplateCustomizer): RestTemplate
    {
        val restTemplate = RestTemplate()
        customizer.customize(restTemplate)
        return restTemplate
    }

    @Bean
    @Qualifier("vanillaRestTemplate")
    fun vanillaRestTemplate(): RestTemplate
    {
        return RestTemplate()
    }
}
